package com.hyperfix.washer.common;

import com.hyperfix.models.washer.pojos.ParamConfig;
import com.hyperfix.models.washer.pojos.ParamsData;
import com.hyperfix.models.washer.pojos.RiskRecord;
import com.hyperfix.washer.service.RiskRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author JiangChunYu
 * 2024/4/25
 */
@Slf4j
@Component
public class ParamValidator {
    @Resource
    private ParamConfigRegistrar paramConfigRegistrar;
    @Resource
    private RiskRecordService riskRecordService;

    private static final String[] PARAMS = {"temperature", "pressure", "oilPressure", "casingPressure", "diffPressure", "flow", "totalFlow"};
    private static final Field[] FIELDS = new Field[PARAMS.length];

    @PostConstruct
    public void init() {
        Class<ParamsData> clazz = ParamsData.class;
        for (int i = 0; i < PARAMS.length; i++) {
            try {
                FIELDS[i] = clazz.getDeclaredField(PARAMS[i]);
                FIELDS[i].setAccessible(true);
            } catch (NoSuchFieldException e) {
                log.error(e.getMessage());
            }
        }
    }

    public void createStatus(ParamsData paramsData) {
        int pipelineId = paramsData.getPipelineId();
        Map<String, ParamConfig> configParamMap = paramConfigRegistrar.getConfigParamMap(pipelineId);
        byte status = (byte) 0xff;
        for (int i = 0; i < PARAMS.length; i++) {
            // 如果没有参数配置 跳过
            if (!configParamMap.containsKey(PARAMS[i])) {
                continue;
            }
            ParamConfig paramConfig = configParamMap.get(PARAMS[i]);
            int validCode = 0;
            double v = 0;
            try {
                v = Double.parseDouble(FIELDS[i].get(paramsData).toString());
                validCode = validate(paramConfig.getLowerLimit(), paramConfig.getUpperLimit(), v);
            } catch (IllegalAccessException e) {
                log.error(e.getMessage());
            }
            if (validCode != 0) {
                // 保存风险记录
                RiskRecord riskRecord = new RiskRecord();
                riskRecord.setPipelineId(pipelineId);
                riskRecord.setTriggerType(validCode);
                riskRecord.setType(PARAMS[i]);
                riskRecord.setValue(v);
                riskRecord.setRecordTime(LocalDateTime.now());
                riskRecordService.asyncSave(riskRecord);
                // 设置参数状态位
                status &= (byte) ~(1 << i++);
            }
        }
        paramsData.setStatus(status);
    }

    /**
     * 校验参数是否正常
     *
     * @param lowerLimit 下限
     * @param upperLimit 上限
     * @param value      参数数值
     * @return int 0 正常 1 超出上限 -1 低于下限
     */
    public int validate(Double lowerLimit, Double upperLimit, double value) {
        // 没有上限和下限
        if (lowerLimit == null && upperLimit == null) {
            return 0;
        }
        // 有上限和下限
        if (lowerLimit != null && upperLimit != null) {
            if (lowerLimit <= value && value <= upperLimit) return 0;
            else if (value < lowerLimit) return -1;
            else return 1;
        }
        // 只有下限
        if (lowerLimit != null) {
            return lowerLimit <= value ? 0 : -1;
        }
        // 只有上限
        return value <= upperLimit ? 0 : 1;
    }
}
